/**
* Base Class that Interfaces an UI Element.
* @author Eduardo Pons
* @version 0.1
*/
import com.thelab.ui.*;

dynamic class com.thelab.ui.UIElement 
{	
	private static var namespace:Array = [];
	private var target;
	private var parent;
	private var self		 :UIElement;	
	private var isDrag  	 :Boolean;
	private var dc_time 	 :Number;
	private var dc_clock	 :Number;
	private var style		 :UIStyle;
	private var update_style :Function;
	private var draw		 :Function;	
	
	var _type:String = "UIElement";
	var _lockstyle		:Boolean;	
	
	var onResize		:Function;
	var onChanged		:Function;
	var onFocus			:Function;
	var onScroll		:Function;
	var onPress         :Function;
	var onHold          :Function;
	var onClickOut      :Function;
	var onDrag			:Function;	
	var onUndrag		:Function;
	var onClick			:Function;	
	var onCheck			:Function;	
	var onDoubleClick	:Function;
	var onMouseOver		:Function;
	var onMouseOut		:Function;	
	//*/
	

	function UIElement(ui_name:String,scope:MovieClip)
	{		
		scope = scope || _root;		
		var d:Number = scope.getNextHighestDepth();
		switch(ui_name)
		{
			case "UILabel": target = scope.createTextField(ui_name+d,d,0,0,1,1); break;
			default: 		target = scope.createEmptyMovieClip(ui_name+d,d); break;
		}		
		parent = scope;		
		init();
	}
	
	private function init()
	{
		self = target.__base = this;
		target.enabled = true;
		dc_time = 200;
		dc_clock = 0;	
		_lockstyle = isDrag = false;		
		style = new UIStyle();
		setEvents();
	}
	
	function get _name():String{ return target._name; }	
	function get _id():Number{	return target.getDepth();	}	
	function set _dclickTime(n:Number) { dc_time = n;  }
	function get _dclickTime():Number {	return dc_time; }	
	function set _fixed(b:Boolean){	isDrag = !b; }
	function get _fixed() {	return !isDrag;	}
	function set _enabled(b:Boolean){	target.enabled = b; }
	function get _enabled() {	return target.enabled;	}
	function get _hide():Boolean { return target._visible; }
	function set _hide(b:Boolean){ target._visible = b; }
	
	function get _x():Number { return target._x; }	
	function set _x(v:Number){ target._x = v; }
	function get _y():Number { return target._y; }
	function set _y(v:Number){ target._y = v; }
	function get _xmouse():Number { return target._xmouse; }		
	function get _ymouse():Number { return target._ymouse; }
	
	function get _width():Number { return target._width; }
	function set _width(v:Number){ onResize(target,v,target._height);target._width = v; }
	function get _height():Number { return target._height; }
	function set _height(v:Number){ onResize(target,target._width,v);target._height = v; }
	function set _rotation(v:Number){ target._rotation = v; }
	function get _rotation():Number { return target._rotation; }
	function get _size():Number { return style.size; }
	function set _size(v:Number){ style.size = v; stylechilds(style); }
	function get _style():UIStyle  { return style.clone();}
	function set _style(st:UIStyle)
	{
		stylechilds(st);
	} 	
	
	private function stylechilds(st)
	{		
		style = st;
		update_style();
		draw();
		for(var i:String in target)
		{			
			if(i!="__base")
			{
				var base = target[i].__base;
				if(base._type == "UIElement")
					if(!base._lockstyle) base.stylechilds(st);				
			}			
		}
	}
	
	private function clearEvents()
	{
		delete target.onRelease;
		delete target.onReleaseOutside
		delete target.onPress;
		delete target.onRollOver;
		delete target.onRollOut;
	}
	
	private function setEvents()
	{
		target.onPress = function()
		{			
			var base =this.__base;
			base.drag();
			base.onPress(base);			
		}
		
		
				
		target.onRelease =  function()
		{
			var base =this.__base;
			
			var elapsed:Number = getTimer() - base.dc_clock;
			if(elapsed <= base.dc_time)
			{
				if(base.onDoubleClick!=undefined)base.onDoubleClick(base);
				else base.onClick(base);
				base.dc_clock = getTimer();
			}
			else
			{				
				base.onClick(base);
				base.dc_clock = getTimer();
			}			
			this.onEnterFrame = undefined;
		}
		
		target.onReleaseOutside = function()
		{
			var base =this.__base;
			this.onEnterFrame = undefined;
			if(base.isDrag) base.onUndrag(base);
			else base.onClickOut(base);
		}
		
		target.onRollOver = function()
		{
			var base =this.__base;
			base.onMouseOver(base);
		}
		target.onRollOut = function()
		{
			var base =this.__base;
			base.onMouseOut(base);
		}
		
		target.onChanged = function(ref:TextField)
		{
			var base =this.__base;
			var len:Number = ref.length;			
			var ch:String = ref.text.charAt(len-1);
			var code:Number = ch.charCodeAt(0);
			if(Key.getCode() == Key.BACKSPACE){ code = Key.BACKSPACE; ch = String.fromCharCode(code); }
			base.onChanged(base,ch,code);
		}
		target.onSetFocus = function()
		{
			var base =this.__base;
			base.onFocus(base,true);
		}
		target.onKillFocus = function()
		{
			var base =this.__base;
			base.onFocus(base,false);
		}
		target.onScroller = function()
		{
			var base =this.__base;			
			base.onScroll(base);
		}
		
	}
	
	function drag()
	{		
		target.__xm = target._xmouse;
		target.__ym = target._ymouse;
		target.onEnterFrame = function()
		{
			var base =this.__base;
			base.onHold(base);
			if(!base.isDrag) return;
			var xm:Number = this.__xm;
			var ym:Number = this.__ym;
			
			this._x = this._parent._xmouse-xm;
			this._y = this._parent._ymouse-ym;
			base.onDrag(base);			
		}
	
	}	
	/*
	private static function walk(obj,a:Array)
	{
			for(var i:String in obj)
			{		
				
				if(typeof(obj[i])=="function") continue;				
				if(UIElement["namespace"].length>0)break;
				if((obj[i])["UIElement"] != undefined)
				{
					a.push(i);					
					UIElement["namespace"] = UIElement["namespace"].concat(a);						
					break;
				}				
				a.push(i);
				walk(obj[i],a);
				a.pop();
				
			}
	}
	
	private static function getNameSpace()
	{
		trace("UIElement> Building Namespace");
		var a:Array = [];
		walk(_global,a);
		
	}
	//*/
	
	static function getUI(ui_name:String,scope:MovieClip)
	{
		var i:Number = 2;
		var a:Array = arguments;
		trace(a);
		switch(ui_name)
		{
			case "CheckBox": return new CheckBox(scope,a[i++],a[i++],a[i++],a[i++],a[i++],a[i++]);
			case "Dot": return new Dot(scope,a[i++],a[i++],a[i++],a[i++],a[i++],a[i++]);
			case "Label": return new Label(scope,a[i++],a[i++],a[i++],a[i++],a[i++],a[i++]);
			case "Slider": return new Slider(scope,a[i++],a[i++],a[i++],a[i++],a[i++],a[i++]);
			case "ToolBox": return new ToolBox(scope,a[i++],a[i++],a[i++],a[i++],a[i++],a[i++]);
			case "Track": return new Track(scope,a[i++],a[i++],a[i++],a[i++],a[i++],a[i++]);
		}
		/*
		if(namespace.length<=0) getNameSpace();
		var ref = _global[namespace[0]];			
		for(var i:Number=1; i<namespace.length;i++) ref = ref[namespace[i]];
		for(var i:String in ref)trace(i);
		return new (ref[ui_name])(scope,arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7]);
		//*/
	}
	
	function remove()
	{		
		switch(typeof(target))
		{
			case "movieclip": target.removeMovieClip(); break;
			default: 		  target.removeTextField(); break;
		}
	}
	
	function addLabel(str:String,px:Number,py:Number,input:Boolean,width:Number,height:Number) : Label
	{
		var l:Label = new Label(target,str,px,py,input);		
		l._style = style;
		onResize(target,target._width,target._height);
		return l;
	}
	
	private function line(p1x:Number,p1y:Number,p2x:Number,p2y:Number)
	{
		target.moveTo(p1x,p1y);
		target.lineTo(p2x,p2y);
	}
	private function square(px:Number,py:Number)
	{
		var s:Number = style.size;
		target.moveTo(px-s,py+s);
		target.lineTo(px+s,py+s);
		target.lineTo(px+s,py-s);
		target.lineTo(px-s,py-s);
		target.lineTo(px-s,py+s);
	}
	private function rectangle(px:Number,py:Number,width:Number,height:Number)
	{
		var w:Number = width;
		var h:Number = height;
		var s:Number = style.size;
		target.moveTo(px,py);
		target.lineTo(px+w,py);
		target.lineTo(px+w,py+h);
		target.lineTo(px,py+h);
		target.lineTo(px,py);
	}
	private function toolbox(px:Number,py:Number,width:Number,height:Number,t_width:Number,t_height:Number)
	{
		var mc:MovieClip = target;
		mc.moveTo(px,py);
		mc.lineTo(px,py-t_height);
		mc.lineTo(px+t_width+10,py-t_height);
		mc.lineTo(px+t_width+15,py);
		mc.lineTo(px+width,py);
		mc.lineTo(px+width,py+height);
		mc.lineTo(px,py+height);
		mc.lineTo(px,py);
	}
	
	
	function toString():String { return _name; }
}